package com.naiterui.ehp.bs.doctor.api;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.doctor.exception.ExceptionCodes;
import com.naiterui.ehp.bs.doctor.utils.PropertyValueConstants;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.faceid.v20180301.FaceidClient;
import com.tencentcloudapi.faceid.v20180301.models.IdCardVerificationRequest;
import com.tencentcloudapi.faceid.v20180301.models.IdCardVerificationResponse;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author guoyongxiang
 * @date 2020/6/15 15:46
 * @since 1.0.0
 */
@Slf4j
public class TencentApi {

    private static Credential cred = new Credential(ConfigUtil.getString("tencent-cloud.api.SecretId"),
        ConfigUtil.getString("tencent-cloud.api.SecretKey"));

    private static final Integer DAY_LIMIT_TIMES = 10;

    @Getter
    enum ResultCode {
        DAY_LIMIT_TIME_ERROR("999", "您当日认证次数已达上限，请检查身份信息，并于明日重试。"),
        AUTH_FAIL_ERROR("998", "实名认证未通过，请检查姓名、身份证号是否填写正确，当日剩余重试次数%d次。"),

        SUCCESS("0", "姓名和身份证号一致"),
        FAIL("-1", "姓名和身份证号不一致"),

        INVALID_LENGTH("-2", "非法身份证号（长度、校验位等不正确"),
        INVALID_NAME("-3", "非法姓名（长度、格式等不正确）"),
        SERVER_ERROR("-4", "证件库服务异常"),
        NO_RECORD("-5", "证件库中无此身份证记录"),

        ;

        private String code;
        private String desc;

        ResultCode(String code, String desc) {
            this.code = code;
            this.desc = desc;
        }
    }

    /**
     * 识别开关(默认开启)
     *
     * @return
     */
    private static boolean getSwitch() {
        Integer enable = (Integer) RedisUtil.valueOps().getObject(PropertyValueConstants.RDS_KEY_USER_AUTH_SWITCH);
        if (enable == null) {
            return true;
        } else if (enable == 1) {
            return false;
        }

        return true;
    }

    private static Integer getLimitCount() {
        Integer count = (Integer) RedisUtil.valueOps().getObject(PropertyValueConstants.RDS_KEY_USER_AUTH_LIMIT);
        if (count == null) {
            return DAY_LIMIT_TIMES;
        }
        return count;
    }

    /**
     * 设置开关
     *
     * @param enable 0:关闭(默认)，1:开启
     * @param limit  每日人脸识别次数上限(默认 {@link #DAY_LIMIT_TIMES})
     */
    public static void setSwitch(Integer enable, Integer limit) {
        if (enable != null) {
            RedisUtil.valueOps().set(PropertyValueConstants.RDS_KEY_USER_AUTH_SWITCH, enable);
        }
        if (limit != null && limit > 0) {
            RedisUtil.valueOps().set(PropertyValueConstants.RDS_KEY_USER_AUTH_LIMIT, limit);
        }
    }

    /**
     * 腾讯云身份证二要素认证
     *
     * @param userId
     * @param idCard
     * @param name
     * @throws BusinessException
     */
    public static void idCardVerification(Long userId, String idCard, String name) throws BusinessException {
        if (!TencentApi.getSwitch()) {
            log.info("实名认证开关关闭 userId:{}, idCard:{}, name:{}", userId, idCard, name);
            return;
        }
        String key = CommonConstant.REDIS_PRE_DR + "tencent_api_limit_idcard_" + DateUtil.getCurrentFormatDate();
        // Long maxTimes = RedisUtil.hashOps().hincrby(key, userId + "", 1L);
        RedisUtil.keyOps().expire(key, 60 * 60 * 24);
        /*if (maxTimes >= DAY_LIMIT_TIMES) {
            throw new BusinessException(ExceptionCodes.EXT_TENCEN_CLOUD_ERR, ResultCode.DAY_LIMIT_TIME_ERROR.getDesc());
        }*/

        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("faceid.tencentcloudapi.com");

        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);

        FaceidClient client = new FaceidClient(cred, "ap-beijing", clientProfile);

        IdCardVerificationRequest req = new IdCardVerificationRequest();
        req.setName(name);
        req.setIdCard(idCard);

        IdCardVerificationResponse resp = null;
        try {
            resp = client.IdCardVerification(req);
        } catch (TencentCloudSDKException e) {
            log.warn("腾讯云实名认证服务异常 name:{}", name, e.getMessage());
            throw new BusinessException(ExceptionCodes.EXT_TENCEN_CLOUD_ERR, e.getMessage());
        }
        if (!ResultCode.SUCCESS.getCode().equals(resp.getResult())) {
            // 计费计次
            /*if (ResultCode.FAIL.getCode().equals(resp.getResult())) {
                //long surplus = getLimitCount() - maxTimes;
                //String msg = String.format(ResultCode.AUTH_FAIL_ERROR.desc, surplus);
                String msg = String.format(ResultCode.AUTH_FAIL_ERROR.desc, "0");
                log.warn("腾讯云实名认证失败(计费) name:{}, code:{}, desc:{}", name, resp.getResult(), resp.getDescription());
                throw new BusinessException(ExceptionCodes.EXT_TENCEN_CLOUD_ERR, msg);
            }*/

            log.warn("腾讯云实名认证失败 name:{}, code:{}, desc:{}", name, resp.getResult(), resp.getDescription());
            throw new BusinessException(ExceptionCodes.EXT_TENCEN_CLOUD_ERR, resp.getDescription());
        }
    }

}
